/*
 * @Author: yangzonglong
 * @Date: 2021-03-03 14:44:59
 * @version: v1.0.0
 * @Descripttion: Input 控制器
 * @LastEditors: yangzonglong
 * @LastEditTime: 2023-03-22 18:55:51
 * @Auditor:
 */
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import { Form, Input, Checkbox, Radio, Button } from 'antd';
import { Select } from '@library';
import Columns from './columns/Columns';
import Sorts from './sorts/Sorts';
import useControlOptions from '../../hooks/useControlOptions';
import ShowPrintController from '../components/ShowPrintController';
import { DataLinkItemProps } from './DataLinkLov';
import { flatControl } from '../../util';
import useFdStore from '../../hooks/useFdStore';
import { ChangeForData } from '../../config';
import { getBindmoduleName, getShowComponentsArray, getModels, getModel, companyModelItf } from '../../util';
import ScreenModal from '../components/optionSetting/screenModal/ScreenModal';
import ScreenModalRule from '../components/optionSetting/screenModal/ScreenModalRules';
import styles from './style.module.scss';

let cacheData = {};
const FormItem = Form.Item;
const fieldNames = { label: 'label', value: 'value' };
const ftStyle = { marginBottom: '8px' };
const dataSource = [
  { label: 'APP', value: 'APP', id: '2' },
  { label: 'API', value: 'API', id: '1' },
];

let urlSourceObj: any = {}; // 缓存api类型下的url对应的字段

interface UrlProps {
  label: string;
  value: string;
  id: string;
}

const Controller = () => {
  const {
    state: { list },
  } = useFdStore();

  const { options: _options, changeFormItemProps, changeControlProps } = useControlOptions<DataLinkItemProps>('inputProps');

  const mapFileds = useRef<any>({});

  const _list = useMemo(() => flatControl(list || []), [list]);

  const [visible, setVisible] = useState(false);
  const [modelsSource, setModelsSource] = useState([]);
  const [modelSource, setModelSource] = useState<any[]>([]);
  const [urlSource, setUrlSource] = useState<UrlProps[]>([]);
  const [componentsArray, setComponentsArray] = useState<any[]>([]);
  const [ruleVisible, setRuleVisible] = useState(false);
  const [bindmoduleName, setBindmoduleName] = useState<any[]>([]);

  const options = useMemo(() => _options.formItemProps, [_options.formItemProps]);;
  const ISAPI = useMemo(() => _options.inputProps?.serviceType === 'API', [_options.inputProps]);


  useEffect(() => {
    if (_options.inputProps?.bindName) {
      setBindmoduleName(getBindmoduleName(_list, _options.inputProps.bindName));
    }
  }, [_list, _options.inputProps]);

  useEffect(() => {
    options?.name && setComponentsArray(getShowComponentsArray(_list, options.name as string));
  }, [_list, options]);

  const onOK = useCallback(
    (data) => {
      setVisible(false);
      changeControlProps('inputProps', { ..._options?.inputProps, screenCondition: data }, true);
    },
    [_options, changeControlProps]
  );

  const onServiceTypeChange = useCallback(
    (serviceType) => {
      cacheData = {};
      urlSourceObj = {};
      setModelsSource([]);
      setModelSource([]);
      setUrlSource([]);
      setBindmoduleName([]);
      // 清除各个缓存source
      changeControlProps(
        'inputProps',
        {
          ..._options?.inputProps,
          serviceType,
          ...ChangeForData.serviceType,
        },
        true
      );
    },
    [changeControlProps, _options]
  );


  const onRuleOK = useCallback(
    (data) => {
      setRuleVisible(false);
      changeControlProps('inputProps', { ..._options?.inputProps, screenConditionRules: data }, true);
    },
    [_options, changeControlProps]
  );

  useEffect(() => {
    // app逻辑
    if (_options.inputProps.serviceType !== 'APP') return;

    if (!_options.inputProps.serviceModuleCode) return;

    if (!cacheData[options?.name + 'ModelsSource']) {
      getModels(_options.inputProps.serviceModuleCode).then((res) => {
        let _res = res?.map((item: string) => ({ label: item, value: item }));
        cacheData[options?.name + 'ModelsSource'] = _res;
        setModelsSource(_res);
      });
    } else if (cacheData[options?.name + 'ModelsSource']) {
      setModelsSource(cacheData[options?.name + 'ModelsSource'] || []);
    }

    if (!_options.inputProps.modulesName) return;

    if (!cacheData[options?.name + 'ModelSource']) {
      getModel(_options.inputProps.serviceModuleCode, _options.inputProps.modulesName).then((res) => {
        cacheData[options?.name + 'ModelSource'] = res;
        setModelSource(res);
      });
    } else if (cacheData[options?.name + 'ModelSource']) {
      setModelSource(cacheData[options?.name + 'ModelSource'] || []);
    }

  }, [_options.inputProps.serviceModuleCode, _options.inputProps.modulesName, _options.inputProps.serviceType, options]);

  useEffect(() => {
    // API逻辑
    if (_options.inputProps.serviceType !== 'API') return;

    if (!_options.inputProps.serviceModuleCode) return;

    if (!cacheData[options?.name + 'UrlSource']) {
      companyModelItf(_options.inputProps.serviceModuleCode).then((res) => {
        let _res = res?.map((item, index) => ({ label: item.itfApi, value: item.itfApi, id: item.itfApi + index }));
        cacheData[options?.name + 'UrlSource'] = _res;
        urlSourceObj = {};
        res?.forEach((item) => {
          urlSourceObj[item.itfApi] = (item?.CompanyModelItfParams || []).map((item: any) => ({ label: item.paramName, value: item.paramField }));
        });

        res?.forEach((item) => {
          let _mapFiled: any = {};
          if (item.mappingEnableFlag) {
            (item?.CompanyModelItfParams || []).forEach((ele: any) => {
              _mapFiled[ele.paramField] = ele.mapField;
            });
            mapFileds.current[item.itfApi] = _mapFiled;
          }
        });


        setUrlSource(_res);
        if (_options.inputProps.modulesUrl) {
          setModelSource(urlSourceObj[_options.inputProps.modulesUrl] || []);
        }
      });
    } else if (cacheData[options?.name + 'UrlSource']) {
      setUrlSource(cacheData[options?.name + 'UrlSource'] || []);
    }

    if (_options.inputProps.modulesUrl) {
      setModelSource(urlSourceObj[_options.inputProps.modulesUrl] || []);
    }
  }, [_options.inputProps.modulesUrl, _options.inputProps.serviceModuleCode, _options.inputProps.serviceType, options]);

  console.log(_options);

  return (
    <>
      <FormItem label="数据绑定ID" tooltip="数据存储的名称/英文/必填">
        <Input onChange={(e) => changeFormItemProps('name', e.target.value)} value={options?.name as string} />
      </FormItem>

      <FormItem label="标题">
        <Input placeholder="请输入" onChange={(e) => changeFormItemProps('label', e.target.value)} value={options?.label as string} />
      </FormItem>

      <FormItem label="标题(EN)">
        <Input placeholder="请输入" onChange={(e) => changeFormItemProps('labelEn', e.target.value)} value={options?.labelEn as string} />
      </FormItem>

      <FormItem label="占位符文本">
        <Input
          placeholder="请输入"
          onChange={(e) => changeControlProps('inputProps', { ..._options?.inputProps, placeholder: e.target.value }, true)}
          value={_options?.inputProps?.placeholder}
        />
      </FormItem>

      <FormItem label="占位符文本(EN)">
        <Input
          placeholder="请输入"
          onChange={(e) => changeControlProps('inputProps', { ..._options?.inputProps, placeholderEn: e.target.value }, true)}
          value={_options?.inputProps?.placeholderEn}
        />
      </FormItem>

      <FormItem label="关联设置" tooltip="关联设置">
        <FormItem>
          <Select
            style={ftStyle}
            value={_options?.inputProps?.serviceType}
            onChange={(e: any) => onServiceTypeChange(e.value)}
            dataSource={dataSource}
            fieldNames={fieldNames}
            url=""
            placeholder="请选择关联类型"
          />
        </FormItem>

        {ISAPI ? (
          <>
            <FormItem>
              <Select
                style={ftStyle}
                value={_options?.inputProps?.serviceModuleCode}
                onChange={async (e: any) => {
                  changeControlProps(
                    'inputProps',
                    {
                      ..._options?.inputProps,
                      serviceModuleCode: e.value,
                      ...ChangeForData.serviceModuleCode,
                    },
                    true
                  );

                  const res = await companyModelItf(e.value);
                  res?.forEach((item) => {
                    urlSourceObj[item.itfApi] = (item?.CompanyModelItfParams || []).map((item: any) => ({ label: item.paramName, value: item.paramField }));
                  });

                  res?.forEach((item) => {
                    let _mapFiled: any = {};
                    if (item.mappingEnableFlag) {
                      (item?.CompanyModelItfParams || []).forEach((ele: any) => {
                        _mapFiled[ele.paramField] = ele.mapField;
                      });
                      mapFileds.current[item.itfApi] = _mapFiled;
                    }
                  });

                  setUrlSource(res?.map((item, index) => ({ label: item.itfApi, value: item.itfApi, id: item.itfApi + index })));
                }}
                fieldNames={{ label: 'serviceModuleName', value: 'serviceModuleCode' }}
                url="/bk/mid/companyx/findModule"
                placeholder="请选择关联应用"
              />
            </FormItem>

            <FormItem>
              <Select
                value={_options?.inputProps?.modulesUrl}
                onChange={(e: any) => {
                  changeControlProps(
                    'inputProps',
                    {
                      ..._options?.inputProps,
                      modulesUrl: e.value,
                      fieldNames: urlSourceObj[e.value] || [],
                      mapFileds: mapFileds.current[e.value] || {},
                      ...ChangeForData.modulesUrl,
                    },
                    true
                  );
                }}
                fieldNames={fieldNames}
                url=""
                dataSource={urlSource}
                placeholder="请选择数据接口"
              />
            </FormItem>
          </>
        ) : (
          <>
            <FormItem>
              <Select
                style={ftStyle}
                value={_options?.inputProps?.serviceModuleCode}
                onChange={(e: any) => {
                  cacheData[options?.name + 'ModelsSource'] = undefined;
                  cacheData[options?.name + 'ModelSource'] = undefined;
                  changeControlProps(
                    'inputProps',
                    {
                      ..._options?.inputProps,
                      serviceModuleCode: e.value,
                      ...ChangeForData.serviceModuleCode,
                    },
                    true
                  );
                }}
                fieldNames={{ label: 'serviceModuleName', value: 'serviceModuleCode' }}
                url="/bk/mid/companyx/findModule"
                placeholder="请选择关联应用"
              />
            </FormItem>

            <FormItem>
              <Select
                value={_options?.inputProps?.modulesName}
                onChange={async (e: any) => {
                  const res = e.value && (await getModel(_options.inputProps.serviceModuleCode, e.value));
                  cacheData[options?.name + 'ModelSource'] = res;
                  changeControlProps(
                    'inputProps',
                    {
                      ..._options?.inputProps,
                      modulesName: e.value,
                      fieldNames: res,
                      ...ChangeForData.modulesName,
                    },
                    true
                  );
                }}
                fieldNames={fieldNames}
                url=""
                dataSource={modelsSource}
                placeholder="请选择数据模型"
              />
            </FormItem>
          </>
        )}

        {/* <FormItem>
          <Select
            style={ftStyle}
            mode="multiple"
            value={_options?.inputProps?.filedShowName?.map((item: any) => item.value) || []}
            onChange={(e: any) => {
              changeControlProps(
                'inputProps',
                { ..._options?.inputProps, filedShowName: e.map((item: any) => ({ value: item.value, label: item.label })) },
                true
              );
            }}
            fieldNames={fieldNames}
            url=""
            dataSource={modelSource}
            placeholder="请选择关联字段"
          />
        </FormItem> */}

        <Columns dataSource={modelSource} changeControlProps={(filedShowName) => {
          changeControlProps(
            'inputProps',
            { ..._options?.inputProps, filedShowName },
            true
          );
        }} columns={_options?.inputProps?.filedShowName || []} />


        <FormItem>
          <Select
            mode="multiple"
            style={ftStyle}
            value={_options?.inputProps?.showFieldName ? Array.isArray(_options?.inputProps?.showFieldName) ? _options?.inputProps?.showFieldName : [{ value: _options?.inputProps?.showFieldName, label: _options?.inputProps?.showFieldName }] : []}
            onChange={(e: any) => {
              changeControlProps('inputProps', {
                ..._options?.inputProps,
                showFieldName: e.map((item: any) => ({ value: item.value, label: item.label }))
              }, true);
            }}
            fieldNames={fieldNames}
            url=""
            dataSource={modelSource}
            placeholder="请选择展示字段"
          />
        </FormItem>

        <FormItem>
          <Select
            mode="multiple"
            value={_options?.inputProps?.extraFieldName?.map((item: any) => item.value) || []}
            onChange={(e: any) => changeControlProps('inputProps', { ..._options?.inputProps, extraFieldName: e.map((item: any) => ({ value: item.value, label: item.label })) }, true)}
            fieldNames={fieldNames}
            url=""
            dataSource={modelSource}
            placeholder="请选择拓展字段"
          />
        </FormItem>
      </FormItem>

      <FormItem label="筛选数据">
        <Button className={styles.btnStyle} block onClick={() => setVisible(true)}>
          设置筛选数据
        </Button>
      </FormItem>

      <FormItem label="关联已有数据">
        <Select
          allowClear
          onClear={() => {
            changeControlProps('inputProps', { ..._options?.inputProps, bindName: undefined, screenConditionRules: [] }, true);
            setBindmoduleName([]);
          }}
          value={_options?.inputProps?.bindName}
          onSelect={(e: any) => {
            changeControlProps('inputProps', { ..._options?.inputProps, bindName: e, screenConditionRules: [] }, true);
            setBindmoduleName(getBindmoduleName(_list, e));
          }}
          dataSource={componentsArray}
          fieldNames={fieldNames}
          url=""
          placeholder="请选择组件"
        />
      </FormItem>

      <FormItem label="筛选条件" tooltip="待填写">
        <Button className={styles.btnStyle} block onClick={() => setRuleVisible(true)}>
          设置筛选条件
        </Button>
      </FormItem>

      <Sorts dataSource={modelSource} changeControlProps={(sortNames) => {
        changeControlProps(
          'inputProps',
          { ..._options?.inputProps, sortNames },
          true
        );
      }} columns={_options?.inputProps?.sortNames || []} />

      <FormItem label="字段占比">
        <Radio.Group
          value={options?.style?.width}
          onChange={(e) => {
            changeFormItemProps('style', { ...options?.style, width: e.target.value });
          }}
        >
          <Radio.Button value={'25%'}>25%</Radio.Button>
          <Radio.Button value={'50%'}>50%</Radio.Button>
          <Radio.Button value={'75%'}>75%</Radio.Button>
          <Radio.Button value={'100%'}>100%</Radio.Button>
        </Radio.Group>
      </FormItem>

      <FormItem className="antd-form-item-row" label="必填">
        <Checkbox onChange={(e) => changeFormItemProps('required', e.target.checked)} checked={options?.required} />
      </FormItem>

      <FormItem className="antd-form-item-row" label="多选">
        <Checkbox onChange={(e) => changeFormItemProps('radio', e.target.checked)} checked={options?.radio} />
      </FormItem>

      <ShowPrintController onChange={changeFormItemProps} print={options?.print} />

      <FormItem className='antd-form-item-row' label="树结构" >
        <Checkbox onChange={(e) => changeFormItemProps('treeStructure', e.target.checked)} checked={options?.treeStructure} />
      </FormItem>

      {options?.treeStructure &&
        <>
          <FormItem label="ID" tooltip="父元素的子数据关联属性">
            <Input value={options?.treeId} onChange={e => { changeFormItemProps('treeId', e.target.value); }} />
          </FormItem>
          <FormItem label="ParentID" tooltip="子数据关联父元素的属性">
            <Input value={options?.treeParentId} onChange={e => { changeFormItemProps('treeParentId', e.target.value); }} />
          </FormItem>
        </>}

      <ScreenModal
        fieldNames={_options?.inputProps?.fieldNames || []}
        dataSource={_options?.inputProps?.screenCondition || []}
        visible={visible}
        onOK={onOK}
        onCancel={() => setVisible(false)}
      />

      <ScreenModalRule
        fieldNames={_options?.inputProps?.fieldNames || []}
        bindmoduleName={bindmoduleName}
        dataSource={_options?.inputProps?.screenConditionRules || []}
        visible={ruleVisible}
        onOK={onRuleOK}
        onCancel={() => setRuleVisible(false)}
      />

    </>
  );
};

export default Controller;
